Leo Lu
(This material is modified from Mansun Kuo’s work)
2016-05-15
## === install required packages ===
pkg_list <- c("magrittr", "httr", "rvest", "stringr", "data.table",
"jsonlite", "RSQLite")
pkg_new <- pkg_list[!(pkg_list %in% installed.packages()[,"Package"])]
if(length(pkg_new)) install.packages(pkg_new)
rm(pkg_new, pkg_list)All RStudio keyboard shortcuts
| Description | Windows & Linux | Mac |
|---|---|---|
| Attempt completion / Indent | Tab | Tab |
| Run current line/selection | Ctrl+Enter | ⌘+↩︎ |
| Comment/uncomment current line/selection | Ctrl+Shift+C | ⌘+⇧+C |
| Reindent lines | Ctrl+I | ⌘+I |
| Insert pipe operator | Ctrl+Shift+M | ⌘+⇧+M |
?: Access ducument in R console??: Search the halp systemCheck your working directory everytime you start to work!
Using getwd/setwd to get/set your working directory.
wd = getwd()
setwd("resources/img")
getwd()
setwd(wd)
getwd()RStudio will set working directory automatically when opening new files.
If you using Projects, RStudio will change working directory for you automatically.
Vector, Matrix, Array, List and Data frame are the most basic data structure in R. These data structures can be mapped into a table according to:
| Homogeneous | Heterogeneous | |
|---|---|---|
| 1d | Atomic vector | List |
| 2d | Matrix | Data frame |
| nd | Array |
v1 <- c(1:10)
v1
#> [1] 1 2 3 4 5 6 7 8 9 10
is.vector(v1)
#> [1] TRUE
length(v1)
#> [1] 10
s1 <- 2
s1
#> [1] 2
is.vector(s1)
#> [1] TRUE
length(s1)
#> [1] 1Lists are also vectors, but not atomic vectors. Lists are generic vectors, with (naturally) different semantics.
Elements in a list can be any kinds type and its length is arbitrary.
Function
strcan help you investigate the structure of a nested list.
li <- list(a = 1:10,
b = c("apple", "banana"))
str(li)#> List of 2
#> $ a: int [1:10] 1 2 3 4 5 6 7 8 9 10
#> $ b: chr [1:2] "apple" "banana"
li2 <- list(li = li,
c = matrix(1:4, nrow = 2))
str(li2)#> List of 2
#> $ li:List of 2
#> ..$ a: int [1:10] 1 2 3 4 5 6 7 8 9 10
#> ..$ b: chr [1:2] "apple" "banana"
#> $ c : int [1:2, 1:2] 1 2 3 4
x1 <- list(c(1, 2), c(3, 4))
x2 <- list(list(1, 2), list(3, 4))
x3 <- list(1, list(2, list(3)))a <- list(a = 1:3, b = "a string", c = pi, d = list(-1, -5))[ extracts a sub-list. The result will always be a list.str(a[1:2])
str(a[4])[[ extracts a single component from a list. It removes a level of hierarchy from the list.y <- list("a", 1L, 1.5, TRUE)
str(y[[1]])
str(y[[4]])$ is a shorthand for extracting named elements of a list. It works similarly to [[ except that you don’t need to use quotes.a$a
a[["b"]]Data frame is a 2-dimension data structure to deal with a table-like heterogeneous data.
df <- data.frame(gender = c("male", "female", "female", "male"),
age = c(33, 18, 24, 26))
## Add new column in a data frame
df$city <- c("Taipei", "Taipei", "Hsinchu", "Taichung")df#> gender age city
#> 1 male 33 Taipei
#> 2 female 18 Taipei
#> 3 female 24 Hsinchu
#> 4 male 26 Taichung
str(df)#> 'data.frame': 4 obs. of 3 variables:
#> $ gender: Factor w/ 2 levels "female","male": 2 1 1 2
#> $ age : num 33 18 24 26
#> $ city : chr "Taipei" "Taipei" "Hsinchu" "Taichung"
All data structures above are objects. They apply different methods and saved as different type internally.
| object | type | class |
|---|---|---|
| c(1, 2.5, 3) | double | numeric |
| c(“male”, “female”, “female”, “male”) | character | character |
| factor(c(“male”, “female”, “female”, “male”)) | integer | factor |
| matrix(1:9, nrow = 3) | integer | matrix |
| list(a = 1:10, b = c(“apple”, “banana”)) | list | list |
| data.frame(a = 1, b = “z”) | list | data.frame |
To understand computations in R, two slogans are helpful:
- Everything that exists is an object.
- Everything that happens is a function call.
John Chambers
`+`
#> function (e1, e2) .Primitive("+")
`<-`
#> .Primitive("<-")
`[`
#> .Primitive("[")
`c`
#> function (..., recursive = FALSE) .Primitive("c")A typical function in R may look like:
f <- function(par1, par2, ...) {
# Some magic happened
return(sth) # return something
}return to specify the return value, the return value will be the last expression inside the function.The basc structure of conditional execution in R is:
if (an expression returns TRUE or FALSE) {
# do something
} else if (another expression returns TRUE or FALSE) {
# do something
} else {
# do something
}Iterate items in R.
# iterate a character vector
for (i in c("a", "b")) {
print(i)
}#> [1] "a"
#> [1] "b"
# nested loop
m <- matrix(numeric(), nrow = 2, ncol = 2)
for (i in 1:nrow(m)) {
for (j in 1:ncol(m)) {
m[i, j] <- i * j
}
}
m#> [,1] [,2]
#> [1,] 1 2
#> [2,] 2 4
tryCatch({
result <- expr
# If you want to use more than one
# R expression in the "try" part then you'll have to
# use curly brackets.
# 'tryCatch()' will return the last evaluated expression
# in case the "try" part was completed successfully
}, warning = function(w) {
message("Here's the original warning message:")
message(w)
# Choose a return value in case of warning
return(NULL)
}, error = function(e) {
message("Here's the original error message:")
message(e)
# Choose a return value in case of error
return(NA)
},
}, finally {
message("Some other message at the end")
# finally:
# Here goes everything that should be executed at the end,
# regardless of success or error.
# If you want more than one expression to be executed, then you
# need to wrap them in curly brackets ({...}); otherwise you could
# just have written 'finally=<expression>'
})https://stackoverflow.com/questions/12193779/how-to-write-trycatch-in-r/12195574#12195574
Pipe argument to right-hand side with %>%
x %>% f is equivalent to f(x)x %>% f(y) is equivalent to f(x, y)x %>% f %>% g %>% h is equivalent to h(g(f(x)))x %>% f(y, .) is equivalent to f(y, x)x %>% f(y, z = .) is equivalent to f(y, z = x)library(magrittr)
iris %>% head()"Ceci n'est pas une pipe" %>% gsub("une", "un", .)A valid HTTP request includes four things:
{httr}{RCurl}download.file()make.socket / read.socket / close.socketUse GET() to request data from a specific resource
## Not Run
library(httr)
library(rvest)
res <- GET(
url = "http://httpbin.org/get",
add_headers(a = 1, b = 2),
set_cookies(c = 1, d = 2),
query = list(q="hihi")
)
content(res, as = "text", encoding = "UTF-8")
content(res, as = "parsed", encoding = "UTF-8")library(magrittr)
library(httr)
library(rvest)#> Loading required package: xml2
url <- "https://www.ptt.cc/bbs/Gossiping/index.html"
doc <- GET(url,
set_cookies('over18'='1')) %>% # over18 cookie
content(as = "text", encoding = "UTF-8") %>%
read_html
doc %>%
html_nodes(xpath = '//*[@id="action-bar-container"]/div/div[2]/a[2]') %>%
html_attr("href")#> [1] "/bbs/Gossiping/index14934.html"
GET(), POST(), HEAD()…http_status: Translate http status code HTTP status codeset_cookies(): set cooklesadd_headers(): add additional headers to a request.headers(): Access response headerscontent(): Retrieve the contents of a request
library(httr)
res <- GET(
url = "http://httpbin.org/get",
add_headers(a = 1, b = 2),
set_cookies(c = 1, d = 2),
query = list(q="hihi")
)
status_code(res)
headers(res)
content(res, type = "text", encoding = "UTF-8")Sometime you may need to provide appropriate HTTP header fields with add_headers() to make a request.
set_cookies to retreve a request.## Not Run
library(httr)
library(rvest)
res1 <- POST(url = "http://httpbin.org/post",
add_headers(a = 1, b = 2),
set_cookies(c = 1, d = 2),
body = "A simple text string")
res2 <- POST(url = "http://httpbin.org/post",
add_headers(a = 1, b = 2),
set_cookies(c = 1, d = 2),
body = list(x = "A simple text string",
y = "hihi"))
identical(res1, res2)
content(res2, as = "text", encoding = "UTF-8")
content(res2, as = "parsed", encoding = "UTF-8")Try to post a message in App Engine GuestBook
res <- GET("http://httpbin.org/get")
# Get an informative description:
http_status(res)
#> $category
#> [1] "Success"
#>
#> $reason
#> [1] "OK"
#>
#> $message
#> [1] "Success: (200) OK"
# Or just access the raw code:
res$status_code
#> [1] 200
# highly recommend using one of these functions whenever you're using httr inside a function to make sure you find out about errors as soon as possible.
warn_for_status(res)
stop_for_status(res)3 ways to access the body of the request:
res <- GET("http://httpbin.org/get")
content(res, "text", encoding = "UTF-8") # accesses the body as a character vector
#> [1] "{\n \"args\": {}, \n \"headers\": {\n \"Accept\": \"application/json, text/xml, application/xml, */*\", \n \"Accept-Encoding\": \"gzip, deflate\", \n \"Host\": \"httpbin.org\", \n \"User-Agent\": \"libcurl/7.43.0 r-curl/0.9.7 httr/1.1.0\"\n }, \n \"origin\": \"123.193.211.51\", \n \"url\": \"http://httpbin.org/get\"\n}\n"(bin <- content(res, "raw")) # raw (binary) vector
#> [1] 7b 0a 20 20 22 61 72 67 73 22 3a 20 7b 7d 2c 20 0a 20 20 22 68 65 61
#> [24] 64 65 72 73 22 3a 20 7b 0a 20 20 20 20 22 41 63 63 65 70 74 22 3a 20
#> [47] 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 2c 20 74 65 78 74
#> [70] 2f 78 6d 6c 2c 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 6d 6c 2c 20
#> [93] 2a 2f 2a 22 2c 20 0a 20 20 20 20 22 41 63 63 65 70 74 2d 45 6e 63 6f
#> [116] 64 69 6e 67 22 3a 20 22 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 22 2c
#> [139] 20 0a 20 20 20 20 22 48 6f 73 74 22 3a 20 22 68 74 74 70 62 69 6e 2e
#> [162] 6f 72 67 22 2c 20 0a 20 20 20 20 22 55 73 65 72 2d 41 67 65 6e 74 22
#> [185] 3a 20 22 6c 69 62 63 75 72 6c 2f 37 2e 34 33 2e 30 20 72 2d 63 75 72
#> [208] 6c 2f 30 2e 39 2e 37 20 68 74 74 72 2f 31 2e 31 2e 30 22 0a 20 20 7d
#> [231] 2c 20 0a 20 20 22 6f 72 69 67 69 6e 22 3a 20 22 31 32 33 2e 31 39 33
#> [254] 2e 32 31 31 2e 35 31 22 2c 20 0a 20 20 22 75 72 6c 22 3a 20 22 68 74
#> [277] 74 70 3a 2f 2f 68 74 74 70 62 69 6e 2e 6f 72 67 2f 67 65 74 22 0a 7d
#> [300] 0a
# writeBin(bin, "myfile.txt") # the highest fidelity way of saving files to disk?httr::contentcontent(res, "parsed")
#> $args
#> named list()
#>
#> $headers
#> $headers$Accept
#> [1] "application/json, text/xml, application/xml, */*"
#>
#> $headers$`Accept-Encoding`
#> [1] "gzip, deflate"
#>
#> $headers$Host
#> [1] "httpbin.org"
#>
#> $headers$`User-Agent`
#> [1] "libcurl/7.43.0 r-curl/0.9.7 httr/1.1.0"
#>
#>
#> $origin
#> [1] "123.193.211.51"
#>
#> $url
#> [1] "http://httpbin.org/get"URL?par1=val1&par2=val2
You can assign query parameter with query()
res1 <- GET(
"http://ecshweb.pchome.com.tw/search/v3.3/all/results?q=sony&page=1&sort=rnk/dc"
)
url2 <- "http://ecshweb.pchome.com.tw/search/v3.3/all/results"
res2 <- GET(url2,
query = list(q="sony", page="1", sort="rnk/dc"))
identical(res1$content, res2$content)#> [1] TRUE
URLencode(" ")#> [1] "%20"
greeting = "你好嗎我很好"
greeting_enc = URLencode(greeting)
greeting_enc#> [1] "%E4%BD%A0%E5%A5%BD%E5%97%8E%E6%88%91%E5%BE%88%E5%A5%BD"
URLdecode(greeting_enc)#> [1] "你好嗎我很好"
paste0("hihi", greeting)#> [1] "hihi你好嗎我很好"
paste0("hihi", greeting, 1:3)#> [1] "hihi你好嗎我很好1" "hihi你好嗎我很好2" "hihi你好嗎我很好3"
paste("hihi", greeting, 1:3, sep = " ", collapse = ",")#> [1] "hihi 你好嗎我很好 1,hihi 你好嗎我很好 2,hihi 你好嗎我很好 3"
sprintf("%s,%s嗎?", "hihi", greeting)#> [1] "hihi,你好嗎我很好嗎?"
rvest::html_node)jsonlite::fromJSON)rvest::html_table, XML::readHtmlTable)XML::xmlToDataFrame)A web scraper designed to work with magrittr.
read_html()html_nodes(doc, css = "<css selector>")html_nodes(doc, xpath = "<css selector>")html_name(): the name of the taghtml_text(): all text inside the taghtml_attr(): contents of a single attributehtml_attrs(): all attributeshtml_table: parse tables into data frameshttr::GET(url) %>% httr::content(as="text") %>% rvest::read_html()Encoding(), iconv() and Sys.setlocale() in Windows (non-UTF8 system).iconvlist() shows all encodings availabe.?Encoding ?iconv
## check out your system locale
Sys.getlocale()
#> [1] "en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8"
aa <- "你好嗎"
Encoding(aa)
#> [1] "UTF-8"
charToRaw(aa)
#> [1] e4 bd a0 e5 a5 bd e5 97 8e
(aa_big5 <- iconv(aa, from = "UTF-8", to = "Big5"))
#> [1] "\xa7A\xa6n\xb6\xdc"
Encoding(aa_big5)
#> [1] "unknown"
harToRaw(aa_big5)
#> [1] a7 41 a6 6e b6 dc# On Windows
Sys.getlocale()
aa <- "你好嗎"
Encoding(aa)
aa_utf8 <- iconv(aa, from = "Big5", to = "UTF-8")
Encoding(aa)<a href = "www.meetup.com/Taiwan-R">
Taiwan R User Group Website
</a>ahref with value "www.meetup.com/Taiwan-R"Taiwan R User Group Websitelibrary(magrittr)
doc = readLines("http://leoluyi.github.io/RCrawler101_201605_Week2/resources/data/demo.html") %>%
paste(collapse = "\n")
cat(doc)#> <!DOCTYPE HTML>
#> <html>
#> <body>
#> <div id='title' class='character'>
#> <a class="link" href="http://data-sci.info/r-crawler-101/">data-sci.info</a>
#> </div>
#> <div id='summary' class='character'>
#> <span class='title'>Number:</span>
#> <span class='number'>2</span>
#> </div>
#> <div id='table1' class='info'>
#> <table style="border-collapse: collapse; border: 1px solid black;">
#> <tr>
#> <th>Name</th>
#> <th>Gender</th>
#> <th>Age</th>
#> </tr>
#> <tr>
#> <td>Alice</td>
#> <td>Female</td>
#> <td>24</td>
#> </tr>
#> <tr>
#> <td>Jane</td>
#> <td>Female</td>
#> <td>26</td>
#> </tr>
#> </table>
#> </div>
#> </body>
#> </html>
library(rvest)
doc <- read_html("http://leoluyi.github.io/RCrawler101_201605_Week2/resources/data/demo.html")
doc#> {xml_document}
#> <html>
#> [1] <body>\n <div id="title" class="character">\n <a c ...
class(doc)#> [1] "xml_document" "xml_node"
CSS practice
http://flukeout.github.io/
doc <- read_html("http://leoluyi.github.io/RCrawler101_201605_Week2/resources/data/demo.html")
doc %>%
html_nodes(css = ".character") %>%
html_text#> [1] "\n data-sci.info\n "
#> [2] "\n Number:\n 2\n "
doc %>%
html_nodes(css = "#title > .link") %>%
html_text#> [1] "data-sci.info"
doc <- read_html("http://leoluyi.github.io/RCrawler101_201605_Week2/resources/data/demo.html")
doc %>%
html_nodes(xpath = "//*[@class='character']") %>%
html_text#> [1] "\n data-sci.info\n "
#> [2] "\n Number:\n 2\n "
doc %>%
html_nodes(xpath = "//div[@id='title']/a") %>%
html_text#> [1] "data-sci.info"
node = doc %>%
html_nodes(css = "#summary") %>%
html_name
node#> [1] "div"
link = doc %>%
html_nodes(xpath = "/html/body/div[@id='title']/a") %>%
html_attr("href")
link#> [1] "http://data-sci.info/r-crawler-101/"
use package xmlview to parse XML content and extract elements.
(rvest::html_table is temperarily not working with unicode data.)
students <- read_html("http://leoluyi.github.io/RCrawler101_201605_Week2/resources/data/demo.html") %>%
html_nodes(xpath = "//table") %>%
html_table()
students#> [[1]]
#> Name Gender Age
#> 1 Alice Female 24
#> 2 Jane Female 26
XML::readHTMLTable()res_text <- GET("https://zh.wikipedia.org/wiki/%E5%9B%BD%E5%AE%B6%E4%BA%BA%E5%8F%A3%E5%88%97%E8%A1%A8") %>%
content("text", encoding = "UTF-8") %>%
`Encoding<-`("UTF-8")
# create `HTMLInternalDocument` for following use
doc <- XML::htmlParse(res_text, encoding = "UTF-8")
class(doc)#> [1] "HTMLInternalDocument" "HTMLInternalDocument" "XMLInternalDocument"
#> [4] "XMLAbstractDocument"
# Parse tables with XML::readHTMLTable()
tables <- XML::readHTMLTable(doc)
# str(tables) # take a look
# View(tables[[2]]) # take a look | 排名 | 國家/地區 | 人口 | 資料日期 | 佔世界比例 | 來源 |
|---|---|---|---|---|---|
| 世界 | 7,323,900,000 | 2016年5月1日 | 100% | 美國人口普查局-世界人口時鐘 | |
| 1 | 中华人民共和国[註 1] | 1,376,400,000 | 2016年5月1日 | 18.8% | 官方人口時鐘 |
| 2 | 印度 | 1,325,500,000 | 2016年5月1日 | 18.1% | 人口時鐘预测 |
| 3 | 美國 | 323,530,000 | 2016年5月1日 | 4.42% | 官方人口時鐘 |
| 4 | 印尼 | 260,460,000 | 2016年5月1日 | 3.56% | 人口时钟预测 |
| 5 | 巴西 | 205,870,000 | 2016年5月1日 | 2.81% | 官方人口時鐘 |
| 6 | 巴基斯坦 | 193,660,000 | 2016年5月1日 | 2.64% | 官方人口時鐘 |
| 7 | 奈及利亞 | 186,360,000 | 2016年5月1日 | 2.55% | 人口时钟预测 |
| 8 | 孟加拉国 | 162,650,000 | 2016年5月1日 | 2.22% | 人口时钟预测 |
| 9 | 俄羅斯[註 2] | 146,380,000 | 2016年5月1日 | 2% | 官方人口時鐘 |
| 10 | 墨西哥 | 128,550,000 | 2016年5月1日 | 1.76% | 人口时钟预测 |
| 11 | 日本 | 126,980,000 | 2016年4月1日 | 1.73% | 日本統計局 |
| 12 | 菲律賓 | 103,020,000 | 2016年5月1日 | 1.41% | 官方人口時鐘 |
| 13 | 衣索比亞 | 101,550,000 | 2016年5月1日 | 1.39% | 人口时钟预测 |
| 14 | 越南 | 94,352,000 | 2016年5月1日 | 1.29% | 人口时钟预测 |
| 15 | 埃及 | 90,885,000 | 2016年5月1日 | 1.24% | 官方人口時鐘 |
| 16 | 德國 | 81,267,000 | 2016年5月1日 | 1.11% | 人口时钟预测 |
| 17 | 土耳其 | 79,884,000 | 2016年1月1日 | 1.09% | 人口时钟预测 |
| 18 | 刚果(金) | 79,346,000 | 2016年5月1日 | 1.08% | 人口时钟预测 |
| 19 | 伊朗 | 79,245,000 | 2016年5月1日 | 1.08% | 官方人口時鐘 |
| 20 | 泰國 | 68,191,000 | 2016年5月1日 | 0.93% | 人口时钟预测 |
| 21 | 英國 | 65,075,000 | 2016年5月1日 | 0.89% | 人口时钟预测 |
| 22 | 法国[註 3] | 64,652,000 | 2016年5月1日 | 0.88% | 人口时钟预测 |
| 23 | 義大利 | 59,851,000 | 2016年5月1日 | 0.82% | 人口时钟预测 |
| 24 | 南非 | 55,027,000 | 2016年5月1日 | 0.75% | 人口时钟预测 |
| 25 | 坦桑尼亚 | 54,907,000 | 2016年5月1日 | 0.75% | 人口时钟预测 |
| 26 | 緬甸 | 54,265,000 | 2016年5月1日 | 0.74% | 人口时钟预测 |
| 27 | 韩国 | 50,514,000 | 2016年5月1日 | 0.69% | 人口时钟预测 |
| 28 | 哥伦比亚 | 48,674,000 | 2016年5月1日 | 0.66% | 官方人口時鐘 |
| 29 | 肯尼亚 | 47,096,000 | 2016年5月1日 | 0.64% | 人口时钟预测 |
| 30 | 西班牙[註 4] | 46,061,000 | 2016年5月1日 | 0.63% | 人口时钟预测 |
| 31 | 阿根廷 | 43,808,000 | 2016年5月1日 | 0.6% | 人口时钟预测 |
| 32 | 烏克蘭[註 5] | 42,561,000 | 2016年5月1日 | 0.58% | 人口时钟预测 |
| 33 | 苏丹 | 40,961,000 | 2016年5月1日 | 0.56% | 人口时钟预测 |
| 34 | 阿尔及利亚 | 40,326,000 | 2016年5月1日 | 0.55% | 人口时钟预测 |
| 35 | 乌干达 | 40,112,000 | 2016年5月1日 | 0.55% | 人口时钟预测 |
| 36 | 波蘭 | 38,626,000 | 2016年5月1日 | 0.53% | 人口时钟预测 |
| 37 | 伊拉克 | 37,459,000 | 2016年5月1日 | 0.51% | 人口时钟预测 |
| 38 | 加拿大 | 36,267,000 | 2016年5月1日 | 0.5% | 人口时钟预测 |
| 39 | 摩洛哥[註 6] | 34,784,000 | 2016年5月1日 | 0.48% | 人口时钟预测 |
| 40 | 阿富汗 | 33,395,000 | 2016年5月1日 | 0.46% | 人口时钟预测 |
| 41 | 沙烏地阿拉伯 | 32,196,000 | 2016年5月1日 | 0.44% | 人口时钟预测 |
| 42 | 秘魯 | 31,734,000 | 2016年5月1日 | 0.43% | 人口时钟预测 |
| 43 | 委內瑞拉 | 31,492,000 | 2016年5月1日 | 0.43% | 人口时钟预测 |
| 44 | 马来西亚 | 31,341,000 | 2016年5月1日 | 0.43% | 官方人口時鐘 |
| 45 | 乌兹别克斯坦 | 30,285,000 | 2016年5月1日 | 0.41% | 人口时钟预测 |
| 46 | 尼泊尔 | 28,800,000 | 2016年5月1日 | 0.39% | 人口时钟预测 |
| 47 | 莫桑比克 | 28,647,000 | 2016年5月1日 | 0.39% | 人口时钟预测 |
| 48 | 加纳 | 27,980,000 | 2016年5月1日 | 0.38% | 人口时钟预测 |
| 49 | 葉門 | 27,435,000 | 2016年5月1日 | 0.37% | 人口时钟预测 |
| 50 | 安哥拉 | 25,727,000 | 2016年5月1日 | 0.35% | 人口时钟预测 |
| 51 | 朝鲜 | 25,271,000 | 2016年5月1日 | 0.35% | 人口时钟预测 |
| 52 | 马达加斯加 | 24,810,000 | 2016年5月1日 | 0.34% | 人口时钟预测 |
| 53 | 澳大利亚[註 7] | 24,070,000 | 2016年5月1日 | 0.33% | 官方人口時鐘 |
| 54 | 喀麦隆 | 23,845,000 | 2016年5月1日 | 0.33% | 人口时钟预测 |
| 55 | 中華民國 | 23,497,000 | 2016年3月1日 | 0.32% | 中華民國統計資訊網 |
| 56 | 科特迪瓦 | 23,162,000 | 2016年5月1日 | 0.32% | 人口时钟预测 |
| 57 | 斯里蘭卡 | 20,808,000 | 2016年5月1日 | 0.28% | 人口时钟预测 |
| 58 | 尼日尔 | 20,564,000 | 2016年5月1日 | 0.28% | 人口时钟预测 |
| 59 | 羅馬尼亞 | 19,371,000 | 2016年5月1日 | 0.26% | 人口时钟预测 |
| 60 | 布吉納法索 | 18,560,000 | 2016年5月1日 | 0.25% | 人口时钟预测 |
| 61 | 智利 | 18,115,000 | 2016年5月1日 | 0.25% | 人口时钟预测 |
| 62 | 叙利亚 | 18,064,000 | 2016年5月1日 | 0.25% | 人口时钟预测 |
| 63 | 马里 | 18,044,000 | 2016年5月1日 | 0.25% | 人口时钟预测 |
| 64 | 哈萨克斯坦 | 17,867,000 | 2016年5月1日 | 0.24% | 人口时钟预测 |
| 65 | 馬拉威 | 17,661,000 | 2016年5月1日 | 0.24% | 人口时钟预测 |
| 66 | 荷蘭 | 16,977,000 | 2016年5月1日 | 0.23% | 官方人口時鐘 |
| 67 | 危地马拉 | 16,636,000 | 2016年5月1日 | 0.23% | 人口时钟预测 |
| 68 | 尚比亞 | 16,628,000 | 2016年5月1日 | 0.23% | 人口时钟预测 |
| 69 | 厄瓜多尔 | 16,363,000 | 2016年5月1日 | 0.22% | 人口时钟预测 |
| 70 | 辛巴威 | 15,887,000 | 2016年5月1日 | 0.22% | 人口时钟预测 |
| 71 | 柬埔寨 | 15,794,000 | 2016年5月1日 | 0.22% | 人口时钟预测 |
| 72 | 塞内加尔 | 15,528,000 | 2016年5月1日 | 0.21% | 人口时钟预测 |
| 73 | 乍得 | 14,433,000 | 2016年5月1日 | 1.97‰ | 人口时钟预测 |
| 74 | 几内亚 | 12,900,000 | 2016年5月1日 | 1.76‰ | 人口时钟预测 |
| 75 | 南蘇丹 | 12,798,000 | 2016年5月1日 | 1.75‰ | 人口时钟预测 |
| 76 | 卢旺达 | 11,851,000 | 2016年5月1日 | 1.62‰ | 人口时钟预测 |
| 77 | 布隆迪 | 11,496,000 | 2016年5月1日 | 1.57‰ | 人口时钟预测 |
| 78 | 古巴 | 11,407,000 | 2016年5月1日 | 1.56‰ | 人口时钟预测 |
| 79 | 比利時 | 11,365,000 | 2016年5月1日 | 1.55‰ | 人口时钟预测 |
| 80 | 突尼西亞 | 11,363,000 | 2016年5月1日 | 1.55‰ | 人口时钟预测 |
| 81 | 贝宁 | 11,132,000 | 2016年5月1日 | 1.52‰ | 人口时钟预测 |
| 82 | 索馬利亞[註 8] | 10,995,000 | 2016年5月1日 | 1.5‰ | 人口时钟预测 |
| 83 | 希臘 | 10,918,000 | 2016年5月1日 | 1.49‰ | 人口时钟预测 |
| 84 | 玻利维亚 | 10,869,000 | 2016年5月1日 | 1.48‰ | 人口时钟预测 |
| 85 | 海地 | 10,840,000 | 2016年5月1日 | 1.48‰ | 人口时钟预测 |
| 86 | 多米尼加 | 10,643,000 | 2016年5月1日 | 1.45‰ | 人口时钟预测 |
| 87 | 捷克 | 10,553,000 | 2016年5月1日 | 1.44‰ | 人口时钟预测 |
| 88 | 葡萄牙 | 10,313,000 | 2016年5月1日 | 1.41‰ | 人口时钟预测 |
| 89 | 阿塞拜疆 | 9,874,900 | 2016年5月1日 | 1.35‰ | 人口时钟预测 |
| 90 | 瑞典 | 9,851,200 | 2016年5月1日 | 1.35‰ | 人口时钟预测 |
| 91 | 匈牙利 | 9,829,100 | 2016年5月1日 | 1.34‰ | 人口时钟预测 |
| 92 | 白俄羅斯 | 9,499,200 | 2016年5月1日 | 1.3‰ | 人口时钟预测 |
| 93 | 阿联酋 | 9,356,500 | 2016年5月1日 | 1.28‰ | 人口时钟预测 |
| 94 | 塔吉克斯坦 | 8,617,000 | 2016年1月1日 | 1.18‰ | 人口时钟预测 |
| 95 | 宏都拉斯 | 8,552,400 | 2016年1月1日 | 1.17‰ | 人口时钟预测 |
| 96 | 奥地利 | 8,441,500 | 2016年1月1日 | 1.15‰ | 人口时钟预测 |
| 97 | 以色列 | 8,424,400 | 2016年1月1日 | 1.15‰ | 人口时钟预测 |
| 98 | 瑞士 | 8,064,300 | 2016年1月1日 | 1.1‰ | 人口时钟预测 |
| 99 | 巴布亚新几内亚 | 7,753,900 | 2016年1月1日 | 1.06‰ | 人口时钟预测 |
| 100 | 多哥 | 7,408,300 | 2016年1月1日 | 1.01‰ | 人口时钟预测 |
| 101 | 香港 | 7,304,100 | 2016年1月1日 | 1‰ | 香港政府統計處網站 |
| 102 | 老挝 | 7,105,200 | 2016年1月1日 | 0.97‰ | 人口时钟预测 |
| 103 | 塞爾維亞[註 9] | 7,090,000 | 2016年1月1日 | 0.97‰ | 人口时钟预测 |
| 104 | 保加利亚 | 7,079,800 | 2016年1月1日 | 0.97‰ | 人口时钟预测 |
| 105 | 巴拉圭 | 7,037,500 | 2016年1月1日 | 0.96‰ | 人口时钟预测 |
| 106 | 约旦 | 6,888,700 | 2016年1月1日 | 0.94‰ | 人口时钟预测 |
| 107 | 厄立特里亚 | 6,760,400 | 2016年1月1日 | 0.92‰ | 人口时钟预测 |
| 108 | 利比亞 | 6,679,000 | 2016年1月1日 | 0.91‰ | 人口时钟预测 |
| 109 | 塞拉利昂 | 6,535,100 | 2016年1月1日 | 0.89‰ | 人口时钟预测 |
| 110 | 薩爾瓦多 | 6,377,900 | 2016年1月1日 | 0.87‰ | 人口时钟预测 |
| 111 | 尼加拉瓜 | 6,257,200 | 2016年1月1日 | 0.85‰ | 人口时钟预测 |
| 112 | 吉尔吉斯斯坦 | 5,934,400 | 2016年1月1日 | 0.81‰ | 人口时钟预测 |
| 113 | 丹麥 | 5,648,000 | 2016年1月1日 | 0.77‰ | 人口时钟预测 |
| 114 | 芬兰[註 10] | 5,491,500 | 2016年1月1日 | 0.75‰ | 官方人口時鐘 |
| 115 | 新加坡 | 5,488,500 | 2016年1月1日 | 0.75‰ | 人口时钟预测 |
| 116 | 斯洛伐克 | 5,432,900 | 2016年1月1日 | 0.74‰ | 人口时钟预测 |
| 117 | 土库曼斯坦 | 5,412,600 | 2016年1月1日 | 0.74‰ | 人口时钟预测 |
| 118 | 挪威[註 11] | 5,085,500 | 2016年1月7日 | 0.69‰ | 人口时钟预测 |
| 119 | 哥斯达黎加 | 5,061,900 | 2016年1月1日 | 0.69‰ | 人口时钟预测 |
| 120 | 中非 | 4,926,400 | 2016年1月1日 | 0.67‰ | 人口时钟预测 |
| 121 | 刚果(布) | 4,850,500 | 2016年1月1日 | 0.66‰ | 人口时钟预测 |
| 122 | 愛爾蘭 | 4,842,100 | 2016年1月1日 | 0.66‰ | 人口时钟预测 |
| 123 | 利比里亚 | 4,749,100 | 2016年1月1日 | 0.65‰ | 人口时钟预测 |
| 124 | 巴勒斯坦[註 12] | 4,705,200 | 2016年1月1日 | 0.64‰ | 人口时钟预测 |
| 125 | 新西蘭 | 4,648,500 | 2016年1月1日 | 0.63‰ | 官方人口時鐘 |
| 126 | 黎巴嫩 | 4,468,300 | 2016年1月1日 | 0.61‰ | 人口时钟预测 |
| 127 | 格鲁吉亚[註 13] | 4,432,500 | 2016年1月1日 | 0.61‰ | 人口时钟预测 |
| 128 | 克罗地亚 | 4,254,600 | 2016年1月1日 | 0.58‰ | 人口时钟预测 |
| 129 | 毛里塔尼亚 | 4,165,800 | 2016年1月1日 | 0.57‰ | 人口时钟预测 |
| 130 | 巴拿马 | 4,025,600 | 2016年1月1日 | 0.55‰ | 人口时钟预测 |
| 131 | 波赫 | 3,835,300 | 2016年1月1日 | 0.52‰ | 人口时钟预测 |
| 132 | 波多黎各 | 3,704,500 | 2016年1月1日 | 0.51‰ | 人口时钟预测 |
| 133 | 阿曼 | 3,590,500 | 2016年1月1日 | 0.49‰ | 人口时钟预测 |
| 134 | 摩尔多瓦[註 14] | 3,549,400 | 2016年1月1日 | 0.48‰ | 人口时钟预测 |
| 135 | 科威特 | 3,533,300 | 2016年1月1日 | 0.48‰ | 人口时钟预测 |
| 136 | 乌拉圭 | 3,426,800 | 2016年1月1日 | 0.47‰ | 人口时钟预测 |
| 137 | 阿尔巴尼亚 | 3,195,900 | 2016年1月1日 | 0.44‰ | 人口时钟预测 |
| 138 | 蒙古 | 3,060,100 | 2016年1月1日 | 0.42‰ | 官方人口時鐘 |
| 139 | 亞美尼亞 | 2,976,600 | 2016年1月1日 | 0.41‰ | 人口时钟预测 |
| 140 | 立陶宛 | 2,954,900 | 2016年1月1日 | 0.4‰ | 人口时钟预测 |
| 141 | 牙买加 | 2,788,000 | 2016年1月1日 | 0.38‰ | 人口时钟预测 |
| 142 | 纳米比亚 | 2,339,400 | 2016年1月1日 | 0.32‰ | 人口时钟预测 |
| 143 | 博茨瓦纳 | 2,140,100 | 2016年1月1日 | 0.29‰ | 人口时钟预测 |
| 144 | 馬其頓 | 2,126,600 | 2016年1月1日 | 0.29‰ | 人口时钟预测 |
| 145 | 卡塔尔 | 2,117,900 | 2016年1月1日 | 0.29‰ | 人口时钟预测 |
| 146 | 賴索托 | 2,078,900 | 2016年1月1日 | 0.28‰ | 人口时钟预测 |
| 147 | 斯洛維尼亞 | 2,043,700 | 2016年1月1日 | 0.28‰ | 人口时钟预测 |
| 148 | 拉脫維亞 | 1,986,100 | 2016年1月1日 | 0.27‰ | 人口时钟预测 |
| 149 | 冈比亚 | 1,969,300 | 2016年1月1日 | 0.27‰ | 人口时钟预测 |
| 150 | 科索沃 | 1,852,400 | 2016年1月1日 | 0.25‰ | 人口时钟预测 |
| 151 | 几内亚比绍 | 1,799,900 | 2016年1月1日 | 0.25‰ | 人口时钟预测 |
| 152 | 加彭 | 1,767,200 | 2016年1月1日 | 0.24‰ | 人口时钟预测 |
| 153 | 巴林 | 1,472,600 | 2016年1月1日 | 0.2‰ | 人口时钟预测 |
| 154 | 千里達及托巴哥 | 1,332,700 | 2016年1月1日 | 0.182‰ | 人口时钟预测 |
| 155 | 模里西斯 | 1,329,600 | 2016年1月1日 | 0.182‰ | 人口时钟预测 |
| 156 | 东帝汶 | 1,309,100 | 2016年1月1日 | 0.179‰ | 人口时钟预测 |
| 157 | 爱沙尼亚 | 1,303,600 | 2016年1月1日 | 0.178‰ | 人口时钟预测 |
| 158 | 斯威士兰 | 1,291,300 | 2016年1月1日 | 0.176‰ | 人口时钟预测 |
| 159 | 賽普勒斯[註 15] | 1,203,900 | 2016年1月1日 | 0.164‰ | 人口时钟预测 |
| 160 | 吉布提 | 939,250 | 2016年1月1日 | 0.128‰ | 人口时钟预测 |
| 161 | 斐济 | 902,980 | 2016年1月1日 | 0.123‰ | 人口时钟预测 |
| 162 | 赤道几内亚 | 817,240 | 2016年1月1日 | 0.112‰ | 人口时钟预测 |
| 163 | 科摩罗 | 798,120 | 2016年1月1日 | 0.109‰ | 人口时钟预测 |
| 164 | 圭亚那 | 781,450 | 2016年1月1日 | 0.107‰ | 人口时钟预测 |
| 165 | 不丹 | 778,130 | 2016年1月1日 | 0.106‰ | 人口时钟预测 |
| 166 | 西撒拉威 | 638,760 | 2016年1月1日 | 0.087‰ | 人口时钟预测 |
| 167 | 蒙特內哥羅 | 604,250 | 2016年1月1日 | 0.083‰ | 人口时钟预测 |
| 168 | 所罗门群岛 | 600,090 | 2016年1月1日 | 0.082‰ | 人口时钟预测 |
| 169 | 澳門 | 576,660 | 2016年1月1日 | 0.079‰ | 人口时钟预测 |
| 170 | 苏里南 | 558,200 | 2016年1月1日 | 0.076‰ | 人口时钟预测 |
| 171 | 卢森堡 | 555,700 | 2016年1月1日 | 0.076‰ | 人口时钟预测 |
| 172 | 佛得角 | 523,670 | 2016年1月1日 | 0.072‰ | 人口时钟预测 |
| 173 | 文莱 | 441,220 | 2016年1月1日 | 0.06‰ | 人口时钟预测 |
| 174 | 馬爾他 | 425,800 | 2016年1月1日 | 0.058‰ | 人口时钟预测 |
| 175 | 巴哈马 | 385,880 | 2016年1月1日 | 0.053‰ | 人口时钟预测 |
| 176 | 伯利兹 | 351,560 | 2016年1月1日 | 0.048‰ | 人口时钟预测 |
| 177 | 馬爾地夫 | 336,410 | 2016年1月1日 | 0.046‰ | 人口时钟预测 |
| 178 | 冰島 | 329,610 | 2016年1月1日 | 0.045‰ | 人口时钟预测 |
| 179 | 巴巴多斯 | 287,390 | 2016年1月1日 | 0.039‰ | 人口时钟预测 |
| 180 | 瓦努阿圖 | 260,820 | 2016年1月1日 | 0.036‰ | 人口时钟预测 |
| 181 | 聖多美和普林西比 | 204,030 | 2016年1月1日 | 0.028‰ | 人口时钟预测 |
| 182 | 萨摩亚 | 193,470 | 2016年1月1日 | 0.026‰ | 人口时钟预测 |
| 183 | 圣卢西亚 | 183,680 | 2016年1月1日 | 0.025‰ | 人口时钟预测 |
| 184 | 關島 | 171,540 | 2016年1月1日 | 0.023‰ | 人口时钟预测 |
| 185 | 库拉索 | 154,840 | 2014年1月1日 | 0.021‰ | Official estimate |
| 186 | 阿鲁巴 | 108,400 | 2016年1月1日 | 0.015‰ | 人口时钟预测 |
| 187 | 聖文森及格瑞那丁 | 107,940 | 2016年1月1日 | 0.015‰ | 人口时钟预测 |
| 188 | 格瑞那達 | 107,830 | 2016年1月1日 | 0.015‰ | 人口时钟预测 |
| 189 | 汤加 | 105,970 | 2016年1月1日 | 0.014‰ | 人口时钟预测 |
| 190 | 基里巴斯 | 105,920 | 2016年1月1日 | 0.014‰ | 人口时钟预测 |
| 191 | 美屬維京群島 | 104,930 | 2016年1月1日 | 0.014‰ | 人口时钟预测 |
| 192 | 密克羅尼西亞聯邦 | 102,100 | 2016年1月1日 | 0.014‰ | 人口时钟预测 |
| 193 | 澤西 | 100,800 | 2014年 | 0.014‰ | 泽西岛官方数据 |
| 194 | 安地卡及巴布達 | 93,758 | 2016年1月1日 | 0.013‰ | 人口时钟预测 |
| 195 | 塞舌尔 | 91,689 | 2016年1月1日 | 0.013‰ | 人口时钟预测 |
| 196 | 马恩岛 | 88,471 | 2016年1月1日 | 0.012‰ | 人口时钟预测 |
| 197 | 安道尔 | 79,403 | 2016年1月1日 | 0.011‰ | 人口时钟预测 |
| 198 | 多米尼克 | 72,297 | 2016年1月1日 | 0.0099‰ | 人口时钟预测 |
| 199 | 百慕大 | 66,364 | 2016年1月1日 | 0.0091‰ | 人口时钟预测 |
| 200 | 开曼群岛 | 63,021 | 2016年1月1日 | 0.0086‰ | 人口时钟预测 |
| 201 | 根西 | 62,950 | 2014年 | 0.0086‰ | 根西岛官方数据 |
| 202 | 美属萨摩亚 | 57,850 | 2016年1月1日 | 0.0079‰ | 人口时钟预测 |
| 203 | 格陵兰 | 56,922 | 2016年1月1日 | 0.0078‰ | 人口时钟预测 |
| 204 | 马绍尔群岛 | 56,787 | 2016年1月1日 | 0.0078‰ | 人口时钟预测 |
| 205 | 圣基茨和尼维斯 | 55,368 | 2016年1月1日 | 0.0076‰ | 人口时钟预测 |
| 206 | 法罗群岛 | 50,361 | 2016年1月1日 | 0.0069‰ | 人口时钟预测 |
| 207 | 北馬里亞納群島 | 45,259 | 2016年1月1日 | 0.0062‰ | 人口时钟预测 |
| 208 | 荷屬聖馬丁 | 38,429 | 2014年 | 0.0052‰ | Official estimate |
| 209 | 列支敦斯登 | 37,623 | 2016年1月1日 | 0.0051‰ | 人口时钟预测 |
| 210 | 摩納哥 | 37,393 | 2016年1月1日 | 0.0051‰ | 人口时钟预测 |
| 211 | 特克斯和凯科斯群岛 | 37,191 | 2016年1月1日 | 0.0051‰ | 人口时钟预测 |
| 212 | 圣马力诺 | 32,572 | 2016年1月1日 | 0.0044‰ | 人口时钟预测 |
| 213 | 直布罗陀 | 29,855 | 2016年1月1日 | 0.0041‰ | 人口时钟预测 |
| 214 | 英屬維爾京群島 | 27,674 | 2016年1月1日 | 0.0038‰ | 人口时钟预测 |
| 215 | 帛琉 | 21,057 | 2016年1月1日 | 0.0029‰ | 人口时钟预测 |
| 216 | 安圭拉 | 16,807 | 2016年1月1日 | 0.0023‰ | 人口时钟预测 |
| 217 | 庫克群島 | 13,238 | 2016年1月1日 | 0.0018‰ | 人口时钟预测 |
| 218 | 瑙鲁 | 10,500 | 2016年1月1日 | 0.0014‰ | 人口时钟预测 |
| 219 | 图瓦卢 | 10,140 | 2016年1月1日 | 0.0014‰ | 人口时钟预测 |
| 220 | 蒙特塞拉特 | 5,144 | 2016年1月1日 | 0.0007‰ | 人口时钟预测 |
| 221 | 聖赫勒拿 | 4,131 | 2016年1月1日 | 0.0006‰ | 人口时钟预测 |
| 222 | 福克蘭群島[註 16] | 3,000 | 2015年7月1日 | 0.0004‰ | IMF estimate for 2014 |
| 223 | 纽埃 | 1,613 | 2011年9月10日 | 0.0002‰ | UN estimate for 2010 |
| 224 | 托克勞 | 1,411 | 2011年8月18日 | 0.0002‰ | UN estimate for 2010 |
| 225 | 梵蒂冈 | 842 | 2014年7月 | 0.0001‰ | Official estimate |
| 226 | 皮特凯恩群岛 | 56 | 2014年 | 0‰ | UN estimate |
Parse XML table with XML::xmlToDataFrame()
Yun can parse JSON with jsonlite in R
library(jsonlite)
library(magrittr)
res <- GET("http://ecshweb.pchome.com.tw/search/v3.3/all/results?q=sony&page=1&sort=rnk/dc")
res_df = content(res, as = "text") %>%
fromJSON() %>%
.$prods # equivelent to (function(x) {x$prods})#> No encoding supplied: defaulting to UTF-8.
str(res_df)#> 'data.frame': 20 obs. of 11 variables:
#> $ Id : chr "DYAI49-A9006HMLV" "DYAD2O-A9006JDQE" "DYAD2J-A9006I085" "DYAD2R-A9006XKSI" ...
#> $ cateId : chr "DYAI49" "DYAD2O" "DYAD2J" "DYAD2R" ...
#> $ picS : chr "/pic/v1/data/item/201509/D/Y/A/I/4/9/sDYAI49-A9006HMLV000_55f2883d1440e.jpg" "/pic/v1/data/item/201510/D/Y/A/D/2/O/sDYAD2O-A9006JDQE000_560e037b08db2.jpg" "/pic/v1/data/item/201509/D/Y/A/D/2/J/sDYAD2J-A9006I085000_55f7f34abd5c9.jpg" "/pic/v1/data/item/201604/D/Y/A/D/2/R/sDYAD2R-A9006XKSI000_56fe3f0b20c2e.jpg" ...
#> $ picB : chr "/pic/v1/data/item/201605/D/Y/A/I/4/9/DYAI49-A9006HMLV000_57353014df35e.jpg" "/pic/v1/data/item/201604/D/Y/A/D/2/O/DYAD2O-A9006JDQE000_57198b2dc111b.jpg" "/pic/v1/data/item/201509/D/Y/A/D/2/J/DYAD2J-A9006I085000_55f7f34aba324.jpg" "/pic/v1/data/item/201605/D/Y/A/D/2/R/DYAD2R-A9006XKSI000_572ff4b5655b1.jpg" ...
#> $ name : chr "SONY SmartBand 2 智慧心率監測手環_ SWR12" "SONY Xperia Z5" "Sony Xperia C5 Ultra E5553 6吋八核自拍機 " "SONY Xperia Z5 Premium" ...
#> $ describe : chr "▼每日強檔‧瘋殺特賣▼SONY SmartBand 2 智慧心率監測手環_ SWR12" "超值▼送32G卡+保護套+保護貼▼SONY Xperia Z5 5.2吋美型防水旗艦機" "送保護套+玻璃保貼Sony Xperia C5 Ultra E5553 6吋八核自拍機 " "▼送32G卡+手機立架+玻璃貼SONY Xperia Z5 Premium" ...
#> $ price : int 3180 16900 8890 19900 11900 16777 20900 4680 2240 13490 ...
#> $ author : chr "" "" "" "" ...
#> $ brand : chr "" "" "" "" ...
#> $ publishDate: chr "" "" "" "" ...
#> $ isPick : int 0 0 0 0 0 0 0 0 0 0 ...
res_list = content(res, as = "parsed")
str(res_list$prods[[1]])res_df2 = data.frame()
for (i in 1:length(res_list$prods)) {
res_df2 = rbind(res_df2,
data.frame(res_list$prods[[i]],
stringsAsFactors = FALSE))
}
identical(res_df, res_df2)do.call + rbinddata.table::rbindlistdo.call + rbindres_df3 = data.frame(do.call(rbind, res_list$prods))
identical(res_df, res_df3)
# An ugly data.frame
str(res_df3)Package: stringr - str_replace(), str_replace_all() - str_extract(), str_extract_all()
library(stringr)
fruits <- c("one apple", "two pears", "three bananas")
str_replace(fruits, "[aeiou]", "-")
#> [1] "-ne apple" "tw- pears" "thr-e bananas"
str_replace_all(fruits, "[aeiou]", "-")
#> [1] "-n- -ppl-" "tw- p--rs" "thr-- b-n-n-s"
shopping_list <- c("apples x4", "bag of flour", "bag of sugar", "milk x2")
str_extract(shopping_list, "[a-z]+")
#> [1] "apples" "bag" "bag" "milk"
str_extract_all(shopping_list, "[a-z]+")
#> [[1]]
#> [1] "apples" "x"
#>
#> [[2]]
#> [1] "bag" "of" "flour"
#>
#> [[3]]
#> [1] "bag" "of" "sugar"
#>
#> [[4]]
#> [1] "milk" "x"行政院環境保護署環境資源資料開放平台提供了一系列的RESTful Api供大家取用,請試著把 紫外線即時監測資料的資料取回來並轉成data.frame
write.csv: write data.frame as csv filedownload.file: save html, jpeg, etcwriteBin: write binary object into diskRSQLite: SQLite connector in Rlibrary(jsonlite)
library(httr)
url = "http://ecshweb.pchome.com.tw/search/v3.3/all/results?q=sony&page=1&sort=rnk/dc"
res_df = GET(url) %>%
content(res, as = "text") %>%
fromJSON() %>%
.$prods # equivelent to (function(x) {x$prods})
write.csv(res_df, "resources/data/pchome.csv", row.names = FALSE)To download a file from the Internet. download.file takes advantage of internet utilities such as curl or wget and may fail if you don’t have any of these utilities in your system.
dest_dir = "resources/data/download"
dir.create(dest_dir, showWarnings = FALSE, recursive = TRUE)
# Download whole HTML file
download.file("https://www.r-project.org/",
file.path(dest_dir, "r-project.org.html"))
# Download image
download.file("https://www.r-project.org/Rlogo.png",
file.path(dest_dir, "Rlogo.png"))
list.files(dest_dir)To write binary data to your local disk.
r = GET("http://opendata.epa.gov.tw/webapi/api/rest/datastore/355000000I-000004/?format=json")
# Set as = "raw" to prevent any character encoding
bin = content(r, as = "raw")
writeBin(bin, "resources/data/download/uv.json")